package com.mmall.concurerency.sync;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Slf4j
public class SynchronizedExample1 {
    //修饰一个代码块
    public  void  test1(int j){
        synchronized (this){
            for (int i = 0; i < 10; i++) {
                log.info("test1 {}-{}",j,i);
            }
        }
    }

    //修饰方法
    public synchronized void test2(int j){
        for (int i = 0; i < 10; i++) {
            log.info("test2 {} - {}",j,i);
        }
    }

    public static void main(String[] args) {
        //测试场景一
//        SynchronizedExample1  synchronizedExample1 = new SynchronizedExample1();
//        ExecutorService  executorService = Executors.newCachedThreadPool();
//        executorService.execute(()->{
//            synchronizedExample1.test1(1);
//        });
//        executorService.execute(()->{
//            // synchronizedExample1.test1(1);
//            synchronizedExample1.test1(2);
//        });

        //        SynchronizedExample1  synchronizedExample1 = new SynchronizedExample1();
//        ExecutorService  executorService = Executors.newCachedThreadPool();
//        executorService.execute(()->{
//            synchronizedExample1.test2(1);
//        });
//        executorService.execute(()->{
//            // synchronizedExample1.test1(1);
//            synchronizedExample1.test2(2);
//        });

        //总结：synchronized  代码块和方法只作用于调用的对象，加上synchronized的话，是先打印0——10再继续输出第2个0-10
        //这里为什么调用线程池，因为是main 如下去调用，本身就只是一个主线程，是同步的，测试没有意义；所以用了线程池，用多个进程来测试
        /**
         *    public void main(){
         *         synchronizedExample1.test1(2);
         *         synchronizedExample1.test1(2);
         *    }
         */
        //用多个对象来测试，如下：

        //测试场景二
        SynchronizedExample1  synchronizedExample1 = new SynchronizedExample1();
        SynchronizedExample1  synchronizedExample2 = new SynchronizedExample1();
        ExecutorService  executorService = Executors.newCachedThreadPool();
        executorService.execute(()->{
            synchronizedExample1.test1(1);
        });
        executorService.execute(()->{
           // synchronizedExample1.test1(1);
            synchronizedExample2.test1(2);
        });
    }
}
